package org.wak.main
{
	
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	
	import org.wak.action.ActionsManager;
	import org.wak.character.CharactersManager;
	import org.wak.dialog.DialogManager;
	import org.wak.gui.GuiManager;
	import org.wak.inventory.InventoryManager;
	import org.wak.main.text.EnglishStringSet;
	import org.wak.main.text.IStringSet;
	import org.wak.main.text.SpanishStringSet;
	import org.wak.main.text.SupportedLanguages;
	import org.wak.scene.SceneManager;
	import org.wak.utils.Stats;
	
	
	/**
	* This class is the orchestra director of the whole running adventure 
	* basicly controls the entry point of the game, initialization , shuting up, everything. 
	*/
	public class AdventureMaster
	{
		// The game main class.
		private var mGameMainClass:DisplayObjectContainer ;
		
		// The adventure settings
		private static var mAdventureSettings:IAdventureSettings ;
		
		// Gra phic layer to draw sceness.
		private var mSceneLayer:Sprite = null ;
		
		// Graphic layer to draw dialogs and messages.
		private var mDialogsLayer:Sprite = null ;
		
		// Graphic layer to draw the gui.
		private var mGuiLayer:Sprite = null ;
		
		// Graphic layer to draw the gui.
		private var mCursorLayer:Sprite = null ;
		
		
		// Default fonts class so the default fonts are embed.
		private var mDefaultFonts:Fonts = null ;
		
		// Instance of resource manager so the fonts are embed.
		private var mResInstance:Object = null ;
		
			
		// Managers: //
		
		// The Scene manager.
		private static var mSceneMngr:SceneManager = null ;
		
		// The Characters manager.
		private static var mCharactersMngr:CharactersManager = null ;
		
		// the actions manager
		private static var mActionsMngr:ActionsManager = null ;
		
		// The graphic user interface manager
		private static var mGuiMngr:GuiManager = null ;
		
		// The inventory items manager.
		private static var mInventoryItemsMngr:InventoryManager = null ;
		
		// Adventure Dialogs manager.
		private static var mDialogsMngr:DialogManager = null ; 
		
		///////////////
		
		// the resource manager class of the game
		private static var mResourceManager:Class ;
		
		// the text manager class for strings
		private static var mTextManager:IStringSet ;
		
		
		///////////////
		
		private var mMonitor:Stats = null ;
		private var mMonitorStats:Boolean = false ;
		
		
		
		/**
		 * Constructor
		 * */
		public function AdventureMaster()
		{
			
			mDefaultFonts = new Fonts();
		}
		
		/**
		 * Getter for the Resource manager class. 
		 * @return Class with the embed resources.
		 * 
		 */		
		public static function get Resources():Class
		{
			return mResourceManager ;
		}
		
		/**
		 * Localized common used text in the interface.
		 * @see IStringSet 
		 * @return Localized texts for interface use.
		 * 
		 */		
		public static function get Texts():IStringSet
		{
			return mTextManager ;
		}
		
		public static function get CharactersMngr():CharactersManager
		{
			return mCharactersMngr ;
		}
		
		public static function get SceneMngr():SceneManager 
		{
			return mSceneMngr ;
		}
		
		public static function get ActionsMngr():ActionsManager 
		{
			return mActionsMngr ;
		}
		
		public static function get GuiMngr():GuiManager 
		{
			return mGuiMngr ;
		}
		
		public static function get InventoryItemsMngr():InventoryManager 
		{
			return mInventoryItemsMngr ;
		}
		
		public static function get DialogMngr():DialogManager 
		{
			return mDialogsMngr ;
		}
		
		//////////
		
		/**
		 * Flag to enable or disable the use of custom mouse cursors. 
		 * @return true if the custom mouse cursors are enabled.
		 * 
		 */		
		public static function get useCustomCursors():Boolean
		{
			return mAdventureSettings.useCustomCursors ;
		}
		
		/**
		 * This is a setter method to give your game main class to the adventureMaster.
		 * @param pMain: Your main class either <code>Sprite</code> or <code>MovieClip</code>.
		 * 
		 * */
		public function SetMainClass(pMain:DisplayObjectContainer):void
		{
			mGameMainClass = pMain ;
		}
		
		
		/**
		 * This is a setter method to give the ResourceManager class to the AdventureMaster.
		 * @param pRes: Your resource manager class
		 * 
		 * */
		public function SetResMngr(pRes:Class):void
		{
			// instanciate the class so the embed fonts are included in the sw
			mResInstance = new pRes();
			
			mResourceManager = pRes ;
		}
		
		/**
		 * Setter method to set the TextManager class containing localized strings. 
		 * @param pTxtClass a IStringSet for the Text Manager.
		 * 
		 */		
		public function SetTextMngr(pTxtClass:IStringSet):void
		{
			mTextManager = pTxtClass ;
		}
		
		
	   /**
	    * This method is to pass the class which holds the global adventure settings.   
		* @param pSettings an <code>IAdventureSettings</code> containing the adventure configuration. 
		*/
		public function SetSettings(pSettings:IAdventureSettings):void
		{
			mAdventureSettings = pSettings ;
		}
		
	   /**
		* Run the initialization of the game.  
		*/
		public function Initialize():void
		{
			
			//trace("Initialize");
			// Load adventure settings
			LoadSettings();
			
			// init layers
			mSceneLayer = new Sprite();
			mDialogsLayer = new Sprite();
			mGuiLayer = new Sprite();
			mCursorLayer = new Sprite();
			
			// add layers
			mGameMainClass.addChild( mSceneLayer );
			mGameMainClass.addChild( mGuiLayer );
			mGameMainClass.addChild( mDialogsLayer );
			mGameMainClass.addChild( mCursorLayer );
			
			
			//mSceneLayer.visible = false 
			//mGuiLayer.visible = false 
			//mDialogsLayer.visible = false
			//mCursorLayer.visible = false 
			
			// if the custom cursors are enabled.
			// disable the mouse for the cursor layer.			
			if( mAdventureSettings.useCustomCursors )
			{
				mCursorLayer.mouseChildren = false ;
				mCursorLayer.mouseEnabled = false ;
			}
			
			
			// Init Text Manager
			InitTextManager( mAdventureSettings.GetDefaultLanguage() );
			
			// Create the managers:
			// create and init InventoryItems Manager
			mInventoryItemsMngr = new InventoryManager();
			//...
			
			// create and init Characters Manager
			mCharactersMngr = new CharactersManager();
			// create and init Dialogs Manager
			//...
			
			// create and init Scene Manager
			mSceneMngr = new SceneManager(mSceneLayer);
			
			// create and init ActionsManager and GUI Manager
			mActionsMngr = new ActionsManager(mAdventureSettings.GetAdventureStyle() );
			mGuiMngr = new GuiManager(mGuiLayer,mCursorLayer, mAdventureSettings.GetAdventureStyle());
			
			// create the dialog manager.
			mDialogsMngr = new DialogManager( mDialogsLayer,  mAdventureSettings.GetAdventureStyle() );
			
			// load the InventoryItems
			if(mResourceManager.hasOwnProperty( XMLScriptNames.InventoryItems ) )
			{
				var fIItemsDefsStr:String = new mResourceManager[XMLScriptNames.InventoryItems];
				mInventoryItemsMngr.LoadItemsDefinitions( new XML(fIItemsDefsStr) );
			}
			else
			{
				throw new Error( XMLScriptNames.InventoryItems +" file missing in ResourceManager.");
			}
			
			// load the characters.
			if(mResourceManager.hasOwnProperty( XMLScriptNames.Characters ) )
			{
				var fCharsDefsStr:String = new mResourceManager[XMLScriptNames.Characters];
				mCharactersMngr.LoadCharsDefinitions( new XML(fCharsDefsStr) );
			}
			else
			{
				throw new Error( XMLScriptNames.CharsDisplay +" file missing in ResourceManager.");
			}
			
			
			if(mResourceManager.hasOwnProperty( XMLScriptNames.CharsDisplay ) )
			{
				var fCharDispDefsStr:String = new mResourceManager[XMLScriptNames.CharsDisplay];
				mCharactersMngr.LoadCharsDisplaysDefinitions( new XML(fCharDispDefsStr));
			}
			else
			{
				throw new Error( XMLScriptNames.CharsDisplay +" file missing in ResourceManager.");
			}
			// load the dialogs.
			if(mResourceManager.hasOwnProperty( XMLScriptNames.Dialogs ) )
			{
				var fDialogsStr:String = new mResourceManager[XMLScriptNames.Dialogs];
				mDialogsMngr.LoadDialogs( new XML(fDialogsStr) );
			}
			else
			{
				throw new Error( XMLScriptNames.Dialogs +" file missing in ResourceManager.");
			}
			//...
			
			// load the scenes.
			if(mResourceManager.hasOwnProperty( XMLScriptNames.Scenes ) )
			{
				var fLocDefsStr:String = new mResourceManager[XMLScriptNames.Scenes];
				mSceneMngr.LoadScenes( new XML(fLocDefsStr));
			}
			else
			{
				throw new Error( XMLScriptNames.Scenes +" file missing in ResourceManager.");
			}
			
			
			
			// load the gui settings
			var fGuiSettings:XML = LoadGuiSettings();
			// Init the gui manager
			mGuiMngr.Initialize(fGuiSettings);
			
			// load the dialogs settings.
			var fDialogsSettings:XML = LoadDialogsSettings();
			//Initialize dialog manager
			mDialogsMngr.Initialize(fDialogsSettings) ;
			
			// Initializes the ActionManager			
			mActionsMngr.Initialize( mSceneMngr, mGuiMngr, mDialogsMngr );
			
			
			
			if(mMonitorStats)
			{
				mMonitor = new Stats()
				mGameMainClass.addChild(mMonitor);
			}
			
			
			
		}
		
		/**
		 * Makes post initialization task to start the adventure. 
		 * 
		 */		
		public function Start():void
		{
			// Start the adventure in the starting Scene.
			mSceneMngr.SetScene( mAdventureSettings.GetPlayerStartingRoom() );
		}
		
		/**
		 * Add a new PuzzleController to the adventure. 
		 * @param pPc a PuzzleControllerBase
		 * 
		 */		
		public function AddPuzzleController( pPc:PuzzleControllerBase ):void
		{
			mActionsMngr.AddPuzzleController(pPc);
		}
		
		/**
		 * Removes a PuzzleController from the adventure. 
		 * @param pPc a PuzzleControllerBase
		 * 
		 */		
		public function RemovePuzzleController( pPc:PuzzleControllerBase ):void
		{
			mActionsMngr.RemovePuzzleController(pPc);
		}
		
		/**
		 * The player's character id used by default. 
		 * @return 
		 * 
		 */		
		public static function get defaultPlayerCharacterId():String
		{
			return mAdventureSettings.GetAdventureDefaultCharacterId() ;
		}
		
		private function LoadSettings():void
		{
			if(mResourceManager.hasOwnProperty( XMLScriptNames.Settings ) )
			{
				var fSettingsStr:String = new mResourceManager[XMLScriptNames.Settings];
				mAdventureSettings = new XMLAdventureSettings( new XML(fSettingsStr));
			}
			else
			{
				throw new Error( XMLScriptNames.Settings +" file missing in ResourceManager.");
			}
			
		}
		
		private function LoadDialogsSettings():XML
		{
			var fRetSettings:XML = null ;
			
			var fSettingsFileName:String = "" ;
			
			if(mAdventureSettings.GetAdventureStyle() == AdventureStyle.ScummStyle)
			{
				fSettingsFileName = XMLScriptNames.ScummDialogs ;
			}
			else if(mAdventureSettings.GetAdventureStyle() == AdventureStyle.SCIStyle)
			{
				fSettingsFileName = XMLScriptNames.SciDialogs ;
			}
			else if(mAdventureSettings.GetAdventureStyle() == AdventureStyle.ModernStyle)
			{
				fSettingsFileName = XMLScriptNames.ModernDialogs ;
			}
			
			if(mResourceManager.hasOwnProperty( fSettingsFileName ) )
			{
				var fSettingsStr:String = new mResourceManager[fSettingsFileName];
				fRetSettings = new XML(fSettingsStr);
				return fRetSettings ;
				 
			}
			
			return null ;
		}
		
		private function LoadGuiSettings():XML
		{
			var fRetSettings:XML = null ;
			
			var fSettingsFileName:String = "" ;
			
			if(mAdventureSettings.GetAdventureStyle() == AdventureStyle.ScummStyle)
			{
				fSettingsFileName = XMLScriptNames.ScummGui ;
			}
			else if(mAdventureSettings.GetAdventureStyle() == AdventureStyle.SCIStyle)
			{
				fSettingsFileName = XMLScriptNames.SciGui ;
			}
			else if(mAdventureSettings.GetAdventureStyle() == AdventureStyle.ModernStyle)
			{
				fSettingsFileName = XMLScriptNames.ModernGui ;
			}
			
			if(mResourceManager.hasOwnProperty( fSettingsFileName ) )
			{
				var fSettingsStr:String = new mResourceManager[fSettingsFileName];
				fRetSettings = new XML(fSettingsStr);
				return fRetSettings ;
				 
			}
			
			return null ;
			
		}
		
		private function InitTextManager( pLanguage:String):void
		{
			switch( pLanguage )
			{
				case SupportedLanguages.English:
					SetTextMngr( new EnglishStringSet() );
				break ;
				
				case SupportedLanguages.Spanish:
					SetTextMngr( new SpanishStringSet() );
				break ;
			}
		}
		
		public function get adventureSettings():IAdventureSettings
		{
			return mAdventureSettings ;
		}
				

	}
}